<?php

namespace app\common\model\xilujob;

use app\common\model\User;
use think\Db;
use think\Exception;
use think\helper\Arr;
use think\Hook;
use think\Model;
use traits\model\SoftDelete;
use function fast\array_get;

class JobApply extends Model
{

    protected $name = 'xilujob_job_apply';
    protected $autoWriteTimestamp = 'int';

    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';

    const STATUS_APPLY_SENT = 0; //已投递
    const STATUS_APPLY_REJECTED = 1; //不合适(拒绝投递， 完结)
    const STATUS_INTERVIEW_SENT = 2; //面试邀请(等待用户回应)
    const STATUS_INTERVIEW_REJECTED = 3; //拒绝面试邀请(完结)
    const STATUS_INTERVIEW_ACCEPTED = 4; //同意面试邀请
    const STATUS_INTERVIEW_FAILED = 5; //面试失败
    const STATUS_INTERVIEW_PASSED = 6; //面试录取
    const STATUS_INTERVIEW_USER_REJECTED = 7; //面试通过拒绝


    const STATUS_TRANSITION = [
        self::STATUS_APPLY_SENT => [self::STATUS_APPLY_REJECTED, self::STATUS_INTERVIEW_SENT],
        self::STATUS_APPLY_REJECTED => [],
        self::STATUS_INTERVIEW_SENT => [],
    ];

    public function user() {
        return $this->belongsTo(User::class,'user_id','id',[],'INNER')->setEagerlyType(0);
    }

    public function job() {
        return $this->belongsTo('Job','job_id','id',[],'INNER')->setEagerlyType(0);
    }

    public function resume() {
        return $this->belongsTo('Resume','resume_id','id',[],'INNER')->setEagerlyType(0);
    }

    public function company() {
        return $this->belongsTo('CompanyProfile','company_id')->setEagerlyType(0);
    }

    public function enterpriseinfo() {
        return $this->belongsTo('EnterpriseInfo', 'company_id','company_id')->setEagerlyType(0);
    }

    public function feedback() {
        return $this->hasOne('ApplyFeedback', 'apply_id', 'id', [], 'LEFT');
    }

    /**
     * 投递简历
     * @param $userId
     * @param $jobId
     * @return $this
     */
    public static function applyJob($userId, $jobId) {
        $applyStatus = static::where('user_id', $userId)->where('job_id',$jobId)
            ->whereIn('status',[self::STATUS_APPLY_SENT,self::STATUS_INTERVIEW_SENT])
            ->value('status');
        $applyStatus = $applyStatus===null ? null : intval($applyStatus);
        if($applyStatus!==null) {
            $errorMsgs = [
                self::STATUS_APPLY_SENT => '您已投递了此职位',
                self::STATUS_INTERVIEW_SENT => '您已收到面试邀请，请到个人中心处理',
            ];
            throw new Exception($errorMsgs[$applyStatus],0);
        }
        $resume = Resume::where('user_id', $userId)->order('id','desc')->field('id,user_id,complete_percent')->find();
        if($resume->complete_percent<=0 || !$resume->personal->realname) {
            throw new Exception('请先完善简历',-1);
        }
        if(!$resume) {
            throw new Exception('请先完善简历',-1);
        }
        $job = Job::field('id,publisher_id,status')->find($jobId);
        if(!$job || $job->status!=Job::STATUS_ENABLED) {
            throw new Exception('职位已下架');
        }
        if($job->publisher_id==$userId) {
            throw new Exception('无法对自己操作');
        }
        Db::startTrans();
        $apply = new static([
            'user_id'=>$userId, 'resume_id'=>$resume->id, 'job_id'=>$job->id, 'company_id'=>$job->publisher_id,
            'status'=>self::STATUS_APPLY_SENT
        ]);
        if($apply->save()) {
            $job->save(['apply_count'=>Db::raw('apply_count+1')]);

            //更新企业 投递数
            CompanyStatistics::where('company_id', $apply->company_id)->update(['job_apply_count'=>Db::raw('job_apply_count+1')]);

            //更新用户 申请职位数
            $applyCount = JobApply::where('user_id', $apply->user_id)->count();
            Member::where('user_id',$apply->user_id)->update(['job_apply_count'=>$applyCount]);

            //刷新简历
            $apply->resume->save(['refreshetime'=>date('Y-m-d H:i:s'),'refresh_date'=>date('Y-m-d')]);

            Hook::listen('xilujob_apply_sent', $apply);
            Db::commit();
            return $apply;
        }else {
            Db::rollback();
            throw new Exception($apply->getError());
        }
    }

    /**
     * 是否正处于投递状态
     * @param $userId
     * @param $jobId
     * @return bool
     */
    public static function isApplying($userId, $jobId) {
        if(!$userId || !$jobId) {
            return false;
        }
        $applying = static::where('user_id', $userId)->where('job_id',$jobId)
            ->whereIn('status',[self::STATUS_APPLY_SENT,self::STATUS_INTERVIEW_SENT])
            ->count();
        return $applying>0;
    }


    /**
     * 改变状态
     * @param $apply
     * @param $status
     * @param string|null $reason
     * @return array|null|string|static
     */
    public static function editApply($apply, $status) {
        if(!$apply instanceof JobApply) {
            $apply = JobApply::get($apply);
        }
        if(!$apply) {
            throw new  Exception('没有投递可以处理');
        }
        $transition = self::STATUS_TRANSITION[$apply->status];
        if(!in_array($status, $transition)) {
            throw new  Exception('状态变更失败');
        }

        $data = ['status'=>$status];
        switch ($status) {
            case self::STATUS_APPLY_REJECTED:
                $data['rejecttime'] = time();
                $eventTag = 'xilujob_apply_rejected';
                break;
            //废弃， 创建面试时更改apply的状态
//            case self::STATUS_INTERVIEW_SENT:
//                $data['accepted_at'] = date('Y-m-d H:i:s');
//                $eventTag = 'interview_sent';
//                //todo: 创建面试邀请
//                break;
        }
        Db::startTrans();
        if($apply->save($data)===false) {
            Db::rollback();
            throw new Exception($apply->getError());
        }
        Hook::listen($eventTag, $apply);
        Db::commit();
        return $apply;
    }

    /**
     * @param $companyId
     * @param $params
     */
    public static function getApplies($companyId, $params=[]) {
        $paginator = self::where('company_id', $companyId)
            ->with([
                'resume',
                'job'=>function($query){$query->withField('id,job_name');},
            ]);
        if($q=array_get($params,'q')) {
            $paginator->join('xilujob_resume_personal_info i', 'resume.id=i.resume_id')
                ->where('i.realname', 'like', "%$q%");
        }
        if($jobId=array_get($params, 'job_id')) {
            $paginator->where('job_id', $jobId);
        }
        if(($resumeStatus=array_get($params, 'resume_status',''))!=='') {
            $paginator->where('resume.status', $resumeStatus);
        }
        if($status=array_get($params, 'status')) {
            $paginator->where('job_apply.status', $status);
        }
        $paginator = $paginator->order('createtime','desc')
            ->paginate();
        return $paginator;
    }

}
